#pragma once

class SceneObject;
class ResourceObject;

class BaseObject
{
	friend class Engine;
	friend class ObjectIterator;

public:
	// Initializes reference counter to 1.
	BaseObject();
	// You can call SetName at most once.
	// Name can be empty string.
	void SetName(const string &Name);

	uint GetRefCount() { return m_RefCount; }
	// Increases reference counter.
	void AddRef();
	// Decreases reference counter.
	// Pass DeferredDelete=true to have Release called later in this/next frame, not now.
	// Use DeferredDelete=true when inside any method of any class inherited from BaseObject.
	void Release(bool AllowDelete = true, bool DeferredDelete = false);

	const string & GetName() { return m_Name; }
	uint GetId() { return m_Id; }

	virtual ResourceObject * AsResourceObject() { return NULL; }
	virtual SceneObject * AsSceneObject() { return NULL; }

	// Set to true to have OnUpdate called every frame.
	void SetUpdate(bool v);
	bool IsOnUpdateList() { return m_IsOnUpdateList; }

protected:
	// Do not expose destructor as public. Call Release instead.
	virtual ~BaseObject();

	virtual void OnUpdate() { }

private:
	string m_Name;
	uint m_RefCount;

	////// For class Engine
	BaseObject *m_PrevObject, *m_NextObject;
	BaseObject *m_PrevUpdateObject, *m_NextUpdateObject;
	bool m_IsOnUpdateList;
	uint m_Id;
	void Delete();
};

template <typename T>
inline void UpdateObjPtr( T * & ptr, T * newVal )
{
	if (newVal == ptr) return;
	if (ptr) ptr->Release();
	ptr = newVal;
	if (ptr) ptr->AddRef();
}
